package com.ssy.lingxi.contract.job;


import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.contract.entity.SignatureAuthLog;
import com.ssy.lingxi.contract.esign.api.SignApi;
import com.ssy.lingxi.contract.esign.constant.EsignConstants;
import com.ssy.lingxi.contract.esign.exception.EsignException;
import com.ssy.lingxi.contract.esign.response.AuthFlowDetailResponse;
import com.ssy.lingxi.contract.model.bo.sign.SignAuthNotifyBO;
import com.ssy.lingxi.contract.model.constant.sign.SignatureAuthStateEnum;
import com.ssy.lingxi.contract.repository.SignatureAuthLogRepository;
import com.ssy.lingxi.contract.service.ISignatureAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 认证流程任务
 * @author yzc
 * @version 2.0.0
 * @date 2021/2/23
 */
@Slf4j
@Component
public class SignAuthCheckJobService {

    @Resource
    private SignatureAuthLogRepository signatureAuthLogRepository;
    @Resource
    private ISignatureAuthService signatureAuthService;
    @Resource
    private SignApi signApi;

    /**
     * 一周的时间(毫秒)
     */
    private static final long WEEK_TIME = 7 * Constants.DAY_TO_MILLISECONDS;

    public void checkSignAuth() {
        List<SignatureAuthLog> signatureAuthLogList = signatureAuthLogRepository.findAll((Specification<SignatureAuthLog>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.equal(root.get("state"), SignatureAuthStateEnum.APPLYING.getCode()));
            predicateList.add(cb.isNotNull(root.get("flowId")));
            predicateList.add(cb.greaterThan(root.get("createTime"), System.currentTimeMillis() - WEEK_TIME));

            return query.where(predicateList.toArray(new Predicate[predicateList.size()])).getRestriction();
        });
        log.info("认证流程查询: 当前有{}条数据在校验, ids:[{}]", signatureAuthLogList.size(), signatureAuthLogList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(",")));
        for (SignatureAuthLog signatureAuthLog : signatureAuthLogList) {
            String flowId = signatureAuthLog.getFlowId();
            try {
                AuthFlowDetailResponse response = signApi.account().authFlowDetail(flowId);

                SignAuthNotifyBO signAuthNotifyBO = new SignAuthNotifyBO();
                signAuthNotifyBO.setFlowId(response.getFlowId());
                signAuthNotifyBO.setStatusDescription(response.getFailReason());

                if (EsignConstants.SignAuthStatus.SUCCESS.equals(response.getFlowStatus())) {
                    // 流程状态为成功,即认证完成
                    signatureAuthService.verifySuccess(signAuthNotifyBO);
                } else if (EsignConstants.SignAuthStatus.FAIL.equals(response.getFlowStatus())) {
                    // 流程状态为失败,即认证失败
                    signatureAuthService.verifyFail(signAuthNotifyBO);
                }
            } catch (EsignException e) {
                log.error("认证流程查询失败", e);
            }
        }
    }
}
